import 'dart:developer';
import 'package:myapp/entities/entities.dart';

import '../models/models.dart';
import 'package:myapp/repositories/article_repo.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class FirebaseArticleRepo implements ArticleRepository {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  @override
  Future<Article> getArticle(String slug) async {
    try {
      DocumentSnapshot documentSnapshot =
          await _firestore.collection('users').doc(slug).get();
      var snapshot = documentSnapshot.data() as Map<String, dynamic>;
      return Article.fromEntity(ArticleEntity.fromDocument(snapshot));
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<List<Article>> getArticles(String tag, String author, bool favorited,
      int limit, int offset) async {
    try {
      var db = _firestore.collection('articles').startAt([offset]).limit(limit);
      return await db.where("author", isEqualTo: author).get().then((value) =>
          value.docs
              .map((e) =>
                  Article.fromEntity(ArticleEntity.fromDocument(e.data())))
              .toList());
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> createArticle(Article article) async {
    try {
      return await _firestore
          .collection('articles')
          .doc(article.slug)
          .set(article.toEntity().toDocument());
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> createComment(String slug, Comment comment) async {
    try {
      List<Comment> comments = await getComments(slug);
      int commentId = comments.length + 1;
      return _firestore
          .collection('articles')
          .doc(slug)
          .collection('comments')
          .doc(commentId.toString())
          .set(comment.toEntity().toDocument());
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> createFavorite(String slug) async {
    try {
      return await _firestore.collection('articles').doc(slug).update(
          {'favorited': true, 'favoritesCount': FieldValue.increment(1)});
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> deleteArticle(String slug) {
    try {
      return _firestore.collection('articles').doc(slug).delete();
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> deleteArticleFavorite(String slug) async {
    try {
      return await _firestore.collection('articles').doc(slug).update(
          {'favorited': false, 'favoritesCount': FieldValue.increment(-1)});
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> deleteComment(String slug, int id) {
    try {
      return _firestore
          .collection('articles')
          .doc(slug)
          .collection('comments')
          .doc(id.toString())
          .delete();
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<List<Article>> getArticlesFeed(int limit, int offset) async {
    try {
      var db = _firestore.collection('articles').startAt([offset]).limit(limit);
      return await db.get().then((value) => value.docs
          .map((e) => Article.fromEntity(ArticleEntity.fromDocument(e.data())))
          .toList());
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<List<Comment>> getComments(String slug) async {
    try {
      // var db = _firestore.collection('articles').startAt([offset]).limit(limit);
      return await _firestore
          .collection('articles')
          .doc(slug)
          .collection('comments')
          .get()
          .then((value) => value.docs
              .map((e) =>
                  Comment.fromEntity(CommentEntity.fromDocument(e.data())))
              .toList());
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<List<String>> getTags(String slug) async {
    try {
      QuerySnapshot querySnapshot = await FirebaseFirestore.instance
        .collection('articles')
        .where('slug', isEqualTo: slug) // 根据作者筛选
        .get();
      Set<String> tags = {};
      for (var doc in querySnapshot.docs) {
      List<dynamic>? tagList = doc['tagList']; // 提取 tagList
      if (tagList != null) {
        tags.addAll(tagList.cast<String>()); // 添加到集合中并去重
      }
    }
    return tags.toList();
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }

  @override
  Future<void> updateArticle(String slug, Article article) async {
    try {
      return await _firestore.collection('articles').doc(slug).set(article.toEntity().toDocument());
    } catch (e) {
      log(e.toString());
      rethrow;
    }
  }
}
